﻿using System;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Restful.Net.Serialization
{
    public class JsonSerializer : ISerializer
    {
        //private const Formatting Formatting = Formatting.Indented;
        private readonly Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();

        private JsonSerializerSettings settings = new JsonSerializerSettings
                                                      {
                                                          NullValueHandling = NullValueHandling.Ignore,
                                                          DefaultValueHandling = DefaultValueHandling.Ignore
                                                      };

        public JsonSerializer()
        {
            serializer.DefaultValueHandling = DefaultValueHandling.Ignore;
            serializer.NullValueHandling = NullValueHandling.Ignore;

        }

        public string ResponseContentType
        {
            get
            {
                return "application/json";
            }
        }

        public bool Supports(string contentType)
        {
            switch (contentType.ToLower())
            {
                case "text/javascript":
                case "text/json":
                case "application/javascript":
                case "application/json":
                case "text/*":
                case "*/*":
                    return true;
                default:
                    return false;
            }
        }

        public void Serialize(object objectToserialize, Stream outputStream)
        {
            string json = JsonConvert.SerializeObject(objectToserialize, Formatting.Indented);
            using (StreamWriter sw = new StreamWriter(outputStream))
            {
                sw.Write(json);
            }
        }

        public object Deserialize(Type t, Stream inputStream)
        {
            using (StreamReader streamReader = new StreamReader(inputStream))
            {
                using (JsonTextReader jtr = new JsonTextReader(streamReader))
                {
                   return serializer.Deserialize(jtr, t);
                }
            }
        }

        public async Task<object> DeserializeAsync(Type t, Stream inputStream)
        {
            using (StreamReader streamReader = new StreamReader(inputStream))
            {
                string json = await streamReader.ReadToEndAsync();
                return await JsonConvert.DeserializeObjectAsync<object>(json, settings);
            }
        }

        public async Task SerializeAsync(object objectToSerialize, Stream outputStream)
        {
            string json = await JsonConvert.SerializeObjectAsync(objectToSerialize, Formatting.Indented);
            using (StreamWriter sw = new StreamWriter(outputStream))
            {
                await sw.WriteAsync(json);
            }
        }
    }
}
